home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpuzzles.3
/
xpuzzles
/
xpuzzles-5.3.1
/
xmlink
/
xmlink.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-05
|
11KB
|
375 lines
/*
# X-BASED MISSING LINK(tm)
#
# xmlink.c
#
###
#
# Copyright (c) 1994 - 96 David Albert Bagley, bagleyd@hertz.njit.edu
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# This program is distributed in the hope that it will be "playable",
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
*/
/*
Version 1: 94/08/30 Xt
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef VMS
#include <unixlib.h>
#define getlogin cuserid
#else
#ifndef apollo
#include <unistd.h>
#endif
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>
#include "Mlink.h"
#include "mlink.xbm"
#ifndef SCOREFILE
#define SCOREFILE "/usr/games/lib/mlink.scores"
#endif
/* The following are in MlinksP.h also */
#define MINFACES 1
#define MAXFACES 8
#define MINTILES 1
#define MAXTILES 8
#define MAXRECORD 32767
#define MAXPROGNAME 80
#define MAXNAME 256
static void Initialize();
static void CallbackMlink();
static void PrintRecord();
static int HandleSolved();
static void PrintState();
static void ReadRecords();
static void WriteRecords();
static Arg arg[1];
static int mlinkRecord[2][2][MAXFACES - MINFACES + 1][MAXTILES - MINTILES + 1];
static int movesDsp = 0;
static char progDsp[64] = "xmlink";
static char recordDsp[16] = "INF";
static char messageDsp[128] = "Welcome";
static char titleDsp[256] = "";
static void Usage()
{
(void) fprintf(stderr, "usage: xmlink\n");
(void) fprintf(stderr,
"\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
(void) fprintf(stderr,
"\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
(void) fprintf(stderr,
"\t[-mono] [-tile {color}] [-{border|bd} {color}]\n");
(void) fprintf(stderr,
"\t[-tiles {int}] [-faces {int}] [-[no]orient] [-[no]middle]\n");
(void) fprintf(stderr,
"\t[-face{0|1|2|3|4|5|6|7} {color}]\n");
exit(1);
}
static XrmOptionDescRec options[] = {
{"-fg", "*mlink.Foreground", XrmoptionSepArg, NULL},
{"-bg", "*Background", XrmoptionSepArg, NULL},
{"-foreground", "*mlink.Foreground", XrmoptionSepArg, NULL},
{"-background", "*Background", XrmoptionSepArg, NULL},
{"-tile", "*mlink.tileColor", XrmoptionSepArg, NULL},
{"-border", "*mlink.tileBorder", XrmoptionSepArg, NULL},
{"-bd", "*mlink.tileBorder", XrmoptionSepArg, NULL},
{"-tiles", "*mlink.tiles", XrmoptionSepArg, NULL},
{"-faces", "*mlink.faces", XrmoptionSepArg, NULL},
{"-orient", "*mlink.orient", XrmoptionNoArg, "TRUE"},
{"-noorient", "*mlink.orient", XrmoptionNoArg, "FALSE"},
{"-middle", "*mlink.middle", XrmoptionNoArg, "TRUE"},
{"-nomiddle", "*mlink.middle", XrmoptionNoArg, "FALSE"},
{"-mono", "*mlink.mono", XrmoptionNoArg, "TRUE"},
{"-face0", "*mlink.faceColor0", XrmoptionSepArg, NULL},
{"-face1", "*mlink.faceColor1", XrmoptionSepArg, NULL},
{"-face2", "*mlink.faceColor2", XrmoptionSepArg, NULL},
{"-face3", "*mlink.faceColor3", XrmoptionSepArg, NULL},
{"-face4", "*mlink.faceColor4", XrmoptionSepArg, NULL},
{"-face5", "*mlink.faceColor5", XrmoptionSepArg, NULL},
{"-face6", "*mlink.faceColor6", XrmoptionSepArg, NULL},
{"-face7", "*mlink.faceColor7", XrmoptionSepArg, NULL}
};
int main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, mlink;
toplevel = XtInitialize(argv[0], "Mlink",
options, XtNumber(options), &argc, argv);
if (argc != 1)
Usage();
XtSetArg(arg[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(toplevel),
RootWindowOfScreen(XtScreen(toplevel)),
(char *) mlink_bits, mlink_width, mlink_height));
XtSetValues(toplevel, arg, 1);
mlink = XtCreateManagedWidget("mlink", mlinkWidgetClass, toplevel,
NULL, 0);
XtAddCallback(mlink, XtNselectCallback, CallbackMlink, NULL);
Initialize(mlink);
XtRealizeWidget(toplevel);
XGrabButton(XtDisplay(mlink), AnyButton, AnyModifier, XtWindow(mlink),
TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, XtWindow(mlink),
XCreateFontCursor(XtDisplay(mlink), XC_crosshair));
XtMainLoop();
#ifdef VMS
return 1;
#else
return 0;
#endif
}
static void Initialize(w)
Widget w;
{
int tiles, faces;
Boolean orient, middle;
XtVaSetValues(w,
XtNstart, FALSE,
NULL);
XtVaGetValues(w,
XtNtiles, &tiles,
XtNfaces, &faces,
XtNorient, &orient,
XtNmiddle, &middle,
NULL);
ReadRecords();
PrintRecord(tiles, faces, orient, middle, recordDsp);
PrintState(XtParent(w), progDsp, tiles, faces, middle, movesDsp,
recordDsp, messageDsp);
}
static void CallbackMlink(w, clientData, callData)
Widget w;
caddr_t clientData;
mlinkCallbackStruct *callData;
{
int tiles, faces;
Boolean orient, middle;
XtVaGetValues(w,
XtNtiles, &tiles,
XtNfaces, &faces,
XtNorient, &orient,
XtNmiddle, &middle,
NULL);
(void) strcpy(messageDsp, "");
switch (callData->reason) {
case MLINK_RESTORE:
case MLINK_RESET:
movesDsp = 0;
break;
case MLINK_BLOCKED:
(void) strcpy(messageDsp, "Blocked");
break;
case MLINK_SPACE:
/*(void) strcpy(messageDsp, "Spaces can't move");*/ /* Too annoying */
break;
case MLINK_IGNORE:
(void) strcpy(messageDsp, "Randomize to start");
break;
case MLINK_MOVED:
movesDsp++;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
case MLINK_CONTROL:
return;
case MLINK_SOLVED:
if (HandleSolved(movesDsp, tiles, faces, orient, middle))
(void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
else
(void) strcpy(messageDsp, "Solved!");
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case MLINK_RANDOMIZE:
movesDsp = 0;
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case MLINK_ORIENT:
movesDsp = 0;
orient = !orient;
PrintRecord(tiles, faces, orient, middle, recordDsp);
XtSetArg(arg[0], XtNorient, orient);
XtSetValues(w, arg, 1);
break;
case MLINK_MIDDLE:
movesDsp = 0;
middle = !middle;
PrintRecord(tiles, faces, orient, middle, recordDsp);
XtSetArg(arg[0], XtNmiddle, middle);
XtSetValues(w, arg, 1);
break;
case MLINK_DEC_X:
movesDsp = 0;
tiles--;
PrintRecord(tiles, faces, orient, middle, recordDsp);
XtSetArg(arg[0], XtNtiles, tiles);
XtSetValues(w, arg, 1);
break;
case MLINK_INC_X:
movesDsp = 0;
tiles++;
PrintRecord(tiles, faces, orient, middle, recordDsp);
XtSetArg(arg[0], XtNtiles, tiles);
XtSetValues(w, arg, 1);
break;
case MLINK_DEC_Y:
movesDsp = 0;
faces--;
PrintRecord(tiles, faces, orient, middle, recordDsp);
XtSetArg(arg[0], XtNfaces, faces);
XtSetValues(w, arg, 1);
break;
case MLINK_INC_Y:
movesDsp = 0;
faces++;
PrintRecord(tiles, faces, orient, middle, recordDsp);
XtSetArg(arg[0], XtNfaces, faces);
XtSetValues(w, arg, 1);
break;
case MLINK_COMPUTED:
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case MLINK_UNDO:
movesDsp--;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
}
PrintState(XtParent(w), progDsp, tiles, faces, middle, movesDsp,
recordDsp, messageDsp);
}
static void PrintRecord(tiles, faces, orient, middle, record)
int tiles, faces;
Boolean orient, middle;
char *record;
{
int i = tiles - MINTILES, j = faces - MINFACES;
int k = (orient) ? 1 : 0, l = (middle) ? 1 : 0;
if (tiles > MAXTILES)
(void) strcpy(record, "NOT RECORDED");
else if (mlinkRecord[l][k][j][i] >= MAXRECORD)
(void) strcpy(record, "NEVER");
else
(void) sprintf(record, "%d", mlinkRecord[l][k][j][i]);
}
static int HandleSolved(counter, tiles, faces, orient, middle)
int counter, tiles, faces;
Boolean orient, middle;
{
int i = tiles - MINTILES, j = faces - MINFACES;
int k = (orient) ? 1 : 0, l = (middle) ? 1 : 0;
if (tiles <= MAXTILES && counter < mlinkRecord[l][k][j][i]) {
mlinkRecord[l][k][j][i] = counter;
if (tiles < 4 || faces < 2)
mlinkRecord[!l][k][j][i] = counter;
WriteRecords();
(void) sprintf(recordDsp, "%d", counter);
return TRUE;
}
return FALSE;
}
static void PrintState(w, prog, tiles, faces, middle, moves, record, message)
Widget w;
char *prog, *record, *message;
int tiles, faces, moves;
Boolean middle;
{
if (middle)
(void) sprintf(titleDsp, "%s: %dx%d norm@ (%d/%s) - %s",
prog, tiles, faces, moves, record, message);
else
(void) sprintf(titleDsp, "%s: %dx%d ind@ (%d/%s) - %s",
prog, tiles, faces, moves, record, message);
XtSetArg(arg[0], XtNtitle, titleDsp);
XtSetValues(w, arg, 1);
}
static void ReadRecords()
{
FILE *fp;
int i, j, k, l, n;
for (l = 0; l < 2; l++)
for (k = 0; k < 2; k++)
for (j = 0; j < MAXFACES - MINFACES + 1; j++)
for (i = 0; i < MAXTILES - MINTILES + 1; i++)
mlinkRecord[l][k][j][i] = MAXRECORD;
if ((fp = fopen(SCOREFILE, "r")) == NULL)
(void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
else {
for (l = 0; l < 2; l++)
for (k = 0; k < 2; k++)
for (j = 0; j < MAXFACES - MINFACES + 1; j++)
for (i = 0; i < MAXTILES - MINTILES + 1; i++) {
(void) fscanf(fp, "%d", &n);
mlinkRecord[l][k][j][i] = n;
}
(void) fclose(fp);
}
}
static void WriteRecords()
{
FILE *fp;
int i, j, k, l;
if ((fp = fopen(SCOREFILE, "w")) == NULL)
(void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
else {
for (l = 0; l < 2; l++) {
for (k = 0; k < 2; k++) {
for (j = 0; j < MAXFACES - MINFACES + 1; j++) {
for (i = 0; i < MAXTILES - MINTILES + 1; i++)
(void) fprintf(fp, "%d ", mlinkRecord[l][k][j][i]);
(void) fprintf(fp, "\n");
}
(void) fprintf(fp, "\n");
}
(void) fprintf(fp, "\n");
}
(void) fclose(fp);
}
}